package nio;

import org.junit.Test;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * 非阻塞式 NIO
 *
 * 一、使用 NIO 完成网络通信的三个核心：
 * 1. 通道（Channel）： 负责连接
 * 2. 缓冲区（Buffer）：负责数据的存储
 * 3. 选择器（Selector）： 是 SelectableChannel 的多路复用器。用于监控 SelectableChanel 的　IO 状况
 */
public class BlockingNIOTest {

    @Test
    public void client() throws Exception {
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
        FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
        ByteBuffer buf = ByteBuffer.allocate(1024);

        // 读取本地文件并发送到服务器
        while (inChannel.read(buf) != -1) {
            buf.flip();
            socketChannel.write(buf);
            buf.clear();
        }

        socketChannel.close();
        inChannel.close();
    }

    @Test
    public void server() throws Exception {
        // 1. 获取通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        FileChannel outChannel = FileChannel.open(Paths.get("1_cp.jpg"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
        // 绑定端口
        serverSocketChannel.bind(new InetSocketAddress(9898));

        // 获取客户端的通道
        SocketChannel socketChannel = serverSocketChannel.accept();

        ByteBuffer buf = ByteBuffer.allocate(1024);

        while (socketChannel.read(buf) != -1) {
            buf.flip();
            outChannel.write(buf);
            buf.clear();
        }

        outChannel.close();
        socketChannel.close();
    }

}
